package asteroids.entity.equipment;

import java.awt.Color;
import java.util.ArrayList;

import org.apache.log4j.Logger;

import asteroids.engine.GameState;
import asteroids.engine.Utils;
import asteroids.entity.GameObject;
import asteroids.entity.Icing;
import asteroids.entity.Ship;
import asteroids.entity.weapon.Bullet;

public class PointDefense extends Equipment
{
    Logger logger = Logger.getLogger(PointDefense.class);

    // double currentPower;
    // double maxPower;
    // double powerRegenRate;
    double powerUsePerShot = 4; // need at least this much power to zap
                                // something - if less, don't draw
    int REFIRE_DELAY = (int) (0.375 * Utils.FRAMES_PER_SECOND);
    long lastFireTime = 0;
    int maxSparks;

    public PointDefense(Ship parent, double maxPower, double regenRate)
    {
        super(parent);
        // this.maxPower = maxPower;
        // powerRegenRate = regenRate;
        // currentPower = maxPower;

        // max_radius = ShapeLib.shipLength * (3.0 / 2);
        max_radius = ship.getMaxRadius() * (3.0 / 2);
        maxSparks = (int) (max_radius * Math.PI);

        objectShape = new Utils.PolarCoordinate[8];
        for( int i = 0; i < 8; i++ )
        {
            objectShape[i] = Utils.createPolarCoordinate(i * (360 / 8), max_radius);
        }
    }

    public PointDefense(Ship parent)
    {
        // reasonable default values?
        // (max charge of two shots)
        this(parent, 20, 2.5 / Utils.FRAMES_PER_SECOND);
    }

    public void respawn()
    {
        icing.clear();
        // currentPower = maxPower;
    }

    public void update(GameState state)
    {
        // make sure we are at the ship's location
        x_position = ship.getXPosition();
        y_position = ship.getYPosition();

        // create icing sparklies
        // if( ship.getEnergy() > powerUsePerShot && ship.isAlive()
        // && state.currentGameTime() - lastFireTime > REFIRE_DELAY )
        // {
        // lastFireTime = state.currentGameTime();
        // int numSparks = (int) ((ship.getEnergy() / (ship.getMaxEnergy())) *
        // maxSparks);
        // // make cool effects
        // for( int i = 0; i < numSparks; i++ )
        // {
        // double rot = Math.random() * 360;
        // Utils.CartesianCoordinate c = Utils.cartesianFromPolar(
        // Utils.createPolarCoordinate(rot, max_radius
        // + (Math.random() * (0.3 * max_radius) - (0.4 * max_radius))))
        // .shiftBy(x_position, y_position);
        // Icing b = new Icing(c.getXComponent(), c.getYComponent(), 1);
        // b.setColor(Color.GRAY);
        // icing.add(b); // create Icing with default shape in a
        // // circle around the ship
        // }
        // }

        // check for targets!
        ArrayList<GameObject> possibleTargets = new ArrayList<GameObject>();
        possibleTargets.addAll(state.getAsteroidManager().getObjects()); // include
                                                                         // all
                                                                         // Asteroids
        for( Ship s : state.getShipManager().getObjects() )
        {
            if( !s.equals(ship) )
            {
                if( !ship.getAffiliation().equals(s.getAffiliation()) )
                {
                    possibleTargets.add(s); // can shoot enemy ships
                }
                possibleTargets.addAll(s.getObjects()); // add all Bullets
            }
        }

        boolean fired = false;
        if( ship.getEnergy() > powerUsePerShot )
        {
            // filter and handle targets
            for( GameObject other : possibleTargets )
            {
                if( other.isAlive() && state.currentGameTime() - lastFireTime >= REFIRE_DELAY
                // &&
                // !other.getAffiliation().equals(ship.getAffiliation())
                        && Utils.gameObjectsCollide(this, other) )
                {
                    logger.trace(ship + " zapping " + other.getType());
                    fired = true;
                    Bullet defense = new Bullet(0, 0, 0, 0, 1, 0, ship);
                    other.collide(defense, defense.getCollisionPower(other));
                    defense.destroy(); // each shot only hits its target
                    defense = null;

                    // make the laser icing
                    Utils.CartesianCoordinate targc = Utils.createCartesianCoordinate(
                            ship.getXPosition() - other.getXPosition(),
                            ship.getYPosition() - other.getYPosition());
                    Utils.PolarCoordinate[] zapShape = { Utils.createPolarCoordinate(0, 0),
                            Utils.polarFromCartesian(targc) };
                    Icing zap = new Icing(other.getXPosition(), other.getYPosition(),
                            Utils.FRAMES_PER_SECOND / 12, zapShape);
                    zap.setColor(Color.YELLOW);
                    // ship.addIcing(zap);
                    ship.addIcing(zap);
                }
            }
        }
        if( fired )
        {
            // takes the same energy whether one target or 10 are hit
            ship.modifyEnergyBy(-powerUsePerShot);
            lastFireTime = state.currentGameTime();
        }
        super.update(state);
    }
}